package com.mjgy.service.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import javax.transaction.Transactional;

import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import com.mjgy.entity.PayLog;
import com.mjgy.repository.PayLogRepository;
import com.mjgy.service.PayLogService;

/**
* @Description: TODO
* @author quanlq
* @date 2018年10月9日
* @version V1.0
*/
@Service
public class PayLogServiceImpl implements PayLogService{
	
	@Autowired
	private PayLogRepository payLogRepository;
	@PersistenceContext
	private EntityManager entityManager;

	@Override
	@Transactional
	public void save(PayLog payLog) {
		payLogRepository.save(payLog);
	}
	
	@Override
	public List<Map<String, Object>> statistic(String startDate, String endDate, Integer page, Integer size){
		StringBuilder sql = new StringBuilder();
		sql.append("SELECT ");
		sql.append("LEFT(create_time, 10)");
		sql.append(",SUM(amount)");
		sql.append(",type");
		sql.append(",COUNT(1)");
		sql.append(" FROM pay_log");
		sql.append(" WHERE status = 1");
		if(!StringUtils.isEmpty(startDate)){
			sql.append(" AND LEFT(create_time, 10) >= :startDate");
		}
		if(!StringUtils.isEmpty(endDate)){
			sql.append(" AND LEFT(create_time, 10) <= :endDate");
		}
		sql.append(" GROUP BY LEFT(create_time, 10), type");
		sql.append(" ORDER BY LEFT(create_time, 10) DESC, type");
		sql.append(" LIMIT :pageIndex, :size");
		
		Query query = entityManager.createNativeQuery(sql.toString());
		if(!StringUtils.isEmpty(startDate)){
			query.setParameter("startDate", startDate);
		}
		if(!StringUtils.isEmpty(endDate)){
			query.setParameter("endDate", endDate);
		}
		query.setParameter("pageIndex", (page-1)*size);
		query.setParameter("size", size);
		List resultList = query.getResultList();
		
		List<Map<String, Object>> list = new ArrayList<>();
		if(CollectionUtils.isEmpty(resultList)){
			return list;
		}
		String date = "";
		BigDecimal contactWay = BigDecimal.ZERO;
		BigDecimal redPacket = BigDecimal.ZERO;
		BigDecimal album = BigDecimal.ZERO;
		BigDecimal broadCast = BigDecimal.ZERO;
		BigDecimal member = BigDecimal.ZERO;
		BigDecimal totalAmount = BigDecimal.ZERO;
		Long albumCount = 0L;
		Long memberCount = 0L;
		for(int i=0; i<resultList.size(); i++){
			Object[] cells = (Object[]) resultList.get(i);
			if(i == 0){
				date = cells[0].toString();
			}
			String tempDate = cells[0].toString();
			BigDecimal tempAmount = (BigDecimal) cells[1];
			Integer tempType = (Integer) cells[2];
			Long tempCount = Long.parseLong(cells[3].toString());
			if(date.equals(tempDate)){
				if(tempType == 0){
					contactWay = contactWay.add(tempAmount);
				}else if(tempType == 1){
					redPacket = redPacket.add(tempAmount);
				}else if(tempType == 2){
					album = album.add(tempAmount);					
					albumCount += tempCount;
				}else if(tempType == 3){
					broadCast = broadCast.add(tempAmount);										
				}else if(tempType == 4){
					member = member.add(tempAmount);															
					memberCount += tempCount;
				}
				totalAmount = totalAmount.add(tempAmount);
			}else{
				Map<String, Object> map = new HashMap<>();
				map.put("date", date);
				map.put("contactWay", contactWay);
				map.put("redPacket", redPacket);
				map.put("album", album);
				map.put("albumCount", albumCount);
				map.put("broadCast", broadCast);
				map.put("member", member);
				map.put("memberCount", memberCount);
				map.put("totalAmount", totalAmount);
				list.add(map);
				
				date = tempDate;
				contactWay = tempType == 0? tempAmount : BigDecimal.ZERO;
				redPacket = tempType == 1? tempAmount : BigDecimal.ZERO;
				album = tempType == 2? tempAmount : BigDecimal.ZERO;
				broadCast = tempType == 3? tempAmount : BigDecimal.ZERO;
				member = tempType == 4? tempAmount : BigDecimal.ZERO;
				albumCount = tempType == 2? tempCount : 0L;
				memberCount = tempType == 4? tempCount : 0L;
				totalAmount = tempAmount;
			}
			if(i == resultList.size() - 1){
				Map<String, Object> map = new HashMap<>();
				map.put("date", date);
				map.put("contactWay", contactWay);
				map.put("redPacket", redPacket);
				map.put("album", album);
				map.put("albumCount", albumCount);
				map.put("broadCast", broadCast);
				map.put("member", member);
				map.put("memberCount", memberCount);
				map.put("totalAmount", totalAmount);
				list.add(map);
			}
		}
		
		return list;
	}

	@Override
	public List<Map<String, Object>> statisticByCity(String date, Integer page, Integer size) {
		StringBuilder sql = new StringBuilder();
		sql.append("SELECT ");
		sql.append("usr.city");
		sql.append(",SUM(pl.amount)");
		sql.append(",pl.type");
		sql.append(",COUNT(1)");
		sql.append(" FROM pay_log pl");
		sql.append(" JOIN e_user usr");
		sql.append(" ON pl.payer_id = usr.id");
		sql.append(" WHERE pl.status = 1");
		if(!StringUtils.isEmpty(date)){
			sql.append(" AND LEFT(pl.create_time, 10) = :date");
		}
		sql.append(" GROUP BY usr.city, pl.type");
		sql.append(" ORDER BY usr.city, pl.type");
		sql.append(" LIMIT :pageIndex, :size");
		
		Query query = entityManager.createNativeQuery(sql.toString());
		if(!StringUtils.isEmpty(date)){
			query.setParameter("date", date);
		}
		query.setParameter("pageIndex", (page-1)*size);
		query.setParameter("size", size);
		List resultList = query.getResultList();
		
		List<Map<String, Object>> list = new ArrayList<>();
		if(CollectionUtils.isEmpty(resultList)){
			return list;
		}
		String city = "";
		BigDecimal contactWay = BigDecimal.ZERO;
		BigDecimal redPacket = BigDecimal.ZERO;
		BigDecimal album = BigDecimal.ZERO;
		BigDecimal broadCast = BigDecimal.ZERO;
		BigDecimal member = BigDecimal.ZERO;
		BigDecimal totalAmount = BigDecimal.ZERO;
		Long albumCount = 0L;
		Long memberCount = 0L;
		for(int i=0; i<resultList.size(); i++){
			Object[] cells = (Object[]) resultList.get(i);
			if(i == 0){
				city = cells[0].toString();
			}
			String tempCity = cells[0].toString();
			BigDecimal tempAmount = (BigDecimal) cells[1];
			Integer tempType = (Integer) cells[2];
			Long tempCount = Long.parseLong(cells[3].toString());
			if(city.equals(tempCity)){
				if(tempType == 0){
					contactWay = contactWay.add(tempAmount);
				}else if(tempType == 1){
					redPacket = redPacket.add(tempAmount);
				}else if(tempType == 2){
					album = album.add(tempAmount);
					albumCount += tempCount;
				}else if(tempType == 3){
					broadCast = broadCast.add(tempAmount);										
				}else if(tempType == 4){
					member = member.add(tempAmount);															
					memberCount += tempCount;
				}
				totalAmount = totalAmount.add(tempAmount);
			}else{
				Map<String, Object> map = new HashMap<>();
				map.put("city", city);
				map.put("contactWay", contactWay);
				map.put("redPacket", redPacket);
				map.put("album", album);
				map.put("albumCount", albumCount);
				map.put("broadCast", broadCast);
				map.put("member", member);
				map.put("memberCount", memberCount);
				map.put("totalAmount", totalAmount);
				list.add(map);
				
				city = tempCity;
				contactWay = tempType == 0? tempAmount : BigDecimal.ZERO;
				redPacket = tempType == 1? tempAmount : BigDecimal.ZERO;
				album = tempType == 2? tempAmount : BigDecimal.ZERO;
				broadCast = tempType == 3? tempAmount : BigDecimal.ZERO;
				member = tempType == 4? tempAmount : BigDecimal.ZERO;
				albumCount = tempType == 2? tempCount : 0L;
				memberCount = tempType == 4? tempCount : 0L;
				totalAmount = tempAmount;
			}
			if(i == resultList.size() - 1){
				Map<String, Object> map = new HashMap<>();
				map.put("city", city);
				map.put("contactWay", contactWay);
				map.put("redPacket", redPacket);
				map.put("album", album);
				map.put("albumCount", albumCount);
				map.put("broadCast", broadCast);
				map.put("member", member);
				map.put("memberCount", memberCount);
				map.put("totalAmount", totalAmount);
				list.add(map);
			}
		}
		
		return list;
	}

}
